package xcmg.device.service.warehouse;

import com.github.pagehelper.PageInfo;
import yb.ecp.fast.infra.util.PageHelperPlus;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xcmg.device.dao.entity.warehouse.WarehouseDeliveryDO;
import xcmg.device.dao.entity.warehouse.WarehouseDeliveryDetailDO;
import xcmg.device.dao.mapper.warehouse.WarehouseDeliveryDetailMapper;
import xcmg.device.infra.ErrorCode;
import xcmg.device.service.vo.warehouse.WarehouseDeliveryDetailVO;
import xcmg.device.service.vo.warehouse.WarehouseDeliveryVO;
import yb.ecp.fast.feign.FastGenClient;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;
import yb.ecp.fast.infra.util.ListUtil;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class WarehouseDeliveryDetailService {

    @Autowired
    private WarehouseDeliveryDetailMapper warehouseDeliveryDetailMapper;

    @Autowired
    private WarehouseDeliveryService warehouseDeliveryService;

    @Autowired
    private FastGenClient fastGenClient;

    /**
     * @Author: WangKe
     * @Description: 新增出库详情记录
     * @Date: 15:19 2018/1/17 0017
     */
    public ErrorCode add(WarehouseDeliveryDetailVO warehouseDeliveryDetailVO){
        ActionResult<String> textResult = fastGenClient.textGuid();
        if (textResult.getCode() != ErrorCode.Success.getCode())
        {
            return ErrorCode.IllegalArument;
        }

        WarehouseDeliveryDetailDO warehouseDeliveryDetailDO = new WarehouseDeliveryDetailDO();
        BeanUtils.copyProperties(warehouseDeliveryDetailVO, warehouseDeliveryDetailDO);

        warehouseDeliveryDetailDO.setId(textResult.getValue());
        warehouseDeliveryDetailDO.setStatus(0);
        warehouseDeliveryDetailDO.setCreateDate(new Date());
        boolean isSuccess = warehouseDeliveryDetailMapper.insert(warehouseDeliveryDetailDO)>0;
        ErrorCode code = isSuccess? ErrorCode.Success: ErrorCode.Failure;
        return code;
    }

    /**
     * @Author: WangKe
     * @Description: 更新相关记录
     * @Date: 15:10 2018/1/18 0018
     */
    public ErrorCode update(WarehouseDeliveryDetailVO warehouseDeliveryDetailVO){
        WarehouseDeliveryDetailDO warehouseDeliveryDetailDO = new WarehouseDeliveryDetailDO();
        BeanUtils.copyProperties(warehouseDeliveryDetailVO, warehouseDeliveryDetailDO);
        return warehouseDeliveryDetailMapper.updateByPrimaryKey(warehouseDeliveryDetailDO)>0? ErrorCode.Success: ErrorCode.WarehouseIdError;
    }

    /**
     * @Author: WangKe
     * @Description: 根据主键删除记录
     * @Date: 15:39 2018/1/17 0017
     */
    public ErrorCode delete(String id){
        int i = warehouseDeliveryDetailMapper.deleteByPrimaryKey(id);
        return i>0? ErrorCode.Success: ErrorCode.WarehouseIdError;
    }

    /**
     * @Author: WangKe
     * @Description: 根据出库单号删除出库详情记录
     * @Date: 15:18 2018/1/17 0017
     */
    public ErrorCode deleteByDeliveryOrder(String deliveryOrder, String orgId){
        return  warehouseDeliveryDetailMapper.deleteByDeliveryOrder(deliveryOrder, orgId)>0? ErrorCode.Success: ErrorCode.WarehouseIdError;
    }

    /**
     * @Author: WangKe
     * @Description: 根据出库单号删除出库详情记录
     * @Date: 2018/1/26 0026
     */
    public ErrorCode deleteByDeliveryOrderList(List<String> orderList, String orgId){
        int i = warehouseDeliveryDetailMapper.removeByOutOrderList(orderList, orgId);
        return i>0? ErrorCode.Success: ErrorCode.WarehouseIdError;
    }

    /**
     * @Author: WangKe
     * @Description: 查询出库记录详情列表
     * @Date: 17:04 2018/1/17 0017
     */
    public PageCommonVO list(SearchCommonVO<WarehouseDeliveryDetailVO> condition) {
        PageCommonVO<WarehouseDeliveryDetailVO> pageCommonVO = new PageCommonVO();
        PageHelperPlus.orderBy("create_date desc");
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        List<WarehouseDeliveryDetailDO> doList = warehouseDeliveryDetailMapper.list(condition.getFilters());
        List<WarehouseDeliveryDetailVO> voList = new ArrayList<WarehouseDeliveryDetailVO>();
        for (WarehouseDeliveryDetailDO entity : doList) {
            WarehouseDeliveryDetailVO model = new WarehouseDeliveryDetailVO();
            BeanUtils.copyProperties(entity, model);
            voList.add(model);
        }
        pageCommonVO.setPageInfo(new PageInfo(doList));
        pageCommonVO.setPageInfoList(voList);
        return pageCommonVO;
    }

    /**
     * @Author: WangKe
     * @Description: 根据条件查找出库记录详情列表
     * @Date: 2018/1/19 0019
     */
    public List<WarehouseDeliveryDetailDO> findListByCondition(WarehouseDeliveryDetailVO vo){
        if(vo == null){
            return new ArrayList<WarehouseDeliveryDetailDO>();
        }
        return warehouseDeliveryDetailMapper.list(vo);
    }

    /**
     * @Author: WangKe
     * @Description:生成出库记录时更新出库详情记录的状态
     * @Date: 2018/1/25 0025
     */
    @Transactional(rollbackFor = Exception.class)
    public Map<String, BigDecimal> updateByOutbound(String deliveryOrder, String materialNo, BigDecimal amount, String orgId)throws Exception{
        Map<String, BigDecimal> map = new HashMap<>();
        map.put("success", BigDecimal.ZERO);
        WarehouseDeliveryDetailVO vo = new WarehouseDeliveryDetailVO();
        vo.setDeliveryOrder(deliveryOrder);
        vo.setMaterialNo(materialNo);
        vo.setOrgId(orgId);
        List<WarehouseDeliveryDetailDO> list = warehouseDeliveryDetailMapper.list(vo);
        if(ListUtil.isNullOrEmpty(list)){
            throw new Exception("更新出库事务单状态时，未找到出库记录");
        }
        
        if(list.size() > 1) {
            BigDecimal totalRealAmount = BigDecimal.ZERO;
            BigDecimal lastAmount = amount;
            for (WarehouseDeliveryDetailDO item : list) {
                if (lastAmount.compareTo(BigDecimal.ZERO) <= 0) {
                    totalRealAmount = totalRealAmount.add(item.getRealAmount());
                    continue;
                }
                if (item.getStatus() == 2 || item.getStatus() == 3) {
                    totalRealAmount = totalRealAmount.add(item.getRealAmount());
                    continue;
                }
                BigDecimal realAmount = item.getRealAmount() == null ? BigDecimal.ZERO : item.getRealAmount();
                BigDecimal subAmount = item.getAmount().subtract(realAmount);
                if (lastAmount.compareTo(subAmount) < 0) {
                    item.setRealAmount(lastAmount.add(realAmount));
                    item.setStatus(1);
                    lastAmount = BigDecimal.ZERO;
                } else {
                    item.setRealAmount(subAmount.add(realAmount));
                    item.setStatus(2);
                    lastAmount = lastAmount.subtract(subAmount);
                }
                totalRealAmount = totalRealAmount.add(item.getRealAmount());
                warehouseDeliveryDetailMapper.updateByPrimaryKey(item);
            }
            if(lastAmount.compareTo(BigDecimal.ZERO) > 0) {
                throw new Exception("实际出库数量不能大于计划出库数量");
            }
            WarehouseDeliveryVO deliveryVO = new WarehouseDeliveryVO();
            deliveryVO.setDeliveryOrder(list.get(0).getDeliveryOrder());
            deliveryVO.setOrgId(orgId);
            List<WarehouseDeliveryDO> deliveryList = warehouseDeliveryService.findList(deliveryVO);
            if(ListUtil.isNullOrEmpty(deliveryList)){
                throw new Exception("更新出库事务单状态时，未找到出库记录");
            }
            
            boolean temp = true;
            boolean finishFlag = false;//强制完成标记： false非强制，true强制完成
            for(WarehouseDeliveryDetailDO model : list){
                if(model.getStatus()==3)
                {
                    finishFlag=true;
                }
                if(model.getAmount() != null && !model.getAmount().equals(model.getRealAmount())){
                    temp = false;
                    break;
                }
            }
            WarehouseDeliveryDO deliveryDO = deliveryList.get(0);
            if (temp && finishFlag)
            {//强制结单状态
                deliveryDO.setStatus(3);
            }
            else if (temp && !finishFlag)
            {//无强制结单状态
                deliveryDO.setStatus(2);
            }
            else
            {
                deliveryDO.setStatus(1);
            }
            map.put("realAmount", totalRealAmount);
            map.put("totalState", new BigDecimal(deliveryDO.getStatus()));
            warehouseDeliveryService.update(deliveryDO);
            map.put("singleState", BigDecimal.ONE);
            map.put("success", BigDecimal.ONE);
            map.put("totalState", BigDecimal.ZERO);
        }else {
            WarehouseDeliveryDetailDO entity = list.get(0);
            BigDecimal totalAmount = entity.getAmount();
            BigDecimal realAmount = entity.getRealAmount();
            
            if(realAmount==null){
                realAmount=new BigDecimal(0);
            }
            BigDecimal sub = amount.add(realAmount);

            if(entity.getStatus()==2)
            {
                throw new Exception("零件已经全部出库完成");
            }
            if(entity.getStatus()==2||entity.getStatus()==3)
            {
                throw new Exception("零件已经结单，不可继续出库");
            }

            boolean success;
            if(sub.compareTo(totalAmount) > 0){
                throw new Exception("实际出库数量不能大于计划出库数量");
            }else if(sub.compareTo(totalAmount) == 0){
                entity.setRealAmount(sub);
                entity.setStatus(2);
            }else{
                entity.setRealAmount(sub);
                entity.setStatus(1);
            }
            map.put("realAmount", entity.getRealAmount());
            map.put("singleState", new BigDecimal(entity.getStatus()));
            map.put("totalState", BigDecimal.ZERO);
            success = warehouseDeliveryDetailMapper.updateByPrimaryKey(entity)>0;
            if(!success){
                throw new Exception("更新出库事务单状态失败");
            }

            boolean temp = true;
            boolean finishFlag = false;//强制完成标记： false非强制，true强制完成
            vo = new WarehouseDeliveryDetailVO();
            vo.setDeliveryOrder(deliveryOrder);
            vo.setOrgId(orgId);
            list = warehouseDeliveryDetailMapper.list(vo);
            for(WarehouseDeliveryDetailDO model : list){
                if(model.getStatus()==3)
                {
                    finishFlag=true;
                }
                if(model.getAmount() != null && !model.getAmount().equals(model.getRealAmount())){
                    temp = false;
                    break;
                }
            }

            WarehouseDeliveryVO deliveryVO = new WarehouseDeliveryVO();
            deliveryVO.setDeliveryOrder(entity.getDeliveryOrder());
            deliveryVO.setOrgId(orgId);
            List<WarehouseDeliveryDO> deliveryList = warehouseDeliveryService.findList(deliveryVO);
            if(ListUtil.isNullOrEmpty(deliveryList)){
                throw new Exception("更新出库事务单状态时，未找到出库记录");
            }
            WarehouseDeliveryDO deliveryDO = deliveryList.get(0);
            if (temp && finishFlag)
            {//强制结单状态
                deliveryDO.setStatus(3);
            }
            else if (temp && !finishFlag)
            {//无强制结单状态
                deliveryDO.setStatus(2);
            }
            else
            {
                deliveryDO.setStatus(1);
            }
            map.put("totalState", new BigDecimal(deliveryDO.getStatus()));
            success = warehouseDeliveryService.update(deliveryDO);
            map.put("success", new BigDecimal(success?1:0));

        }
        return map;
    }
}
